/*
 * Copyright (c) 2010, Leon Dang f3it.com
 *           (c) 2010, Andrew Korolev redfox14 at gmail dot com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *   * Neither the name of the authors nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "userdetails.h"
#include <QtGui>
#include <QContactManager>
#include <QContactFilter>
#include <QContactDetailFilter>
#include <QContactName>
#include <QContactThumbnail>
#include <QContact>
#include <QContactDetail>
#include <QContactPhoneNumber>
#include <QIcon>

#include <QTime> // performance profiling

#include "settings.h"


UserDetails::UserDetails(QString &name, QString &number, QWidget *parent)
	: QDialog(parent)
{
	setAttribute( Qt::WA_DeleteOnClose );
	QPushButton *cb;
	QPushButton *sb;

	m_name = new QString(name);
	m_number = new QString(number);

	if (name != "")
		setWindowTitle(name);
	else if (number != "")
		setWindowTitle(number);
	else {
		setWindowTitle("Unknown Number");
		return;
	}


	QVBoxLayout *mainLayout = new QVBoxLayout;

	const QContact *contact = UserDetails::getUserDetails(m_name);
	if (contact == NULL) {
		QString style = QString("text-align: left;"
								"color: rgb(230,230,50);");

		cb = new QPushButton(QIcon(QString(IMG_CELL)), QString("Phone %1").arg(number));
		sb = new QPushButton(QIcon(QString(IMG_SMS_READ)), QString("&SMS %1").arg(number));
		sb->setStyleSheet(style);
		cb->setStyleSheet(style);
		QHBoxLayout *hLayout = new QHBoxLayout;
		hLayout->addWidget(cb);
		hLayout->addWidget(sb);
		mainLayout->addLayout(hLayout);
		setLayout(mainLayout);

		return;
	}

	thumb = new QFrame();
	thumb->setFrameShape(QFrame::StyledPanel);
	thumb->setFixedSize(160,160);

	pix = new QLabel(thumb);

	QContactThumbnail cthumb = contact->detail(QContactThumbnail::DefinitionName);
	//qDebug() << "Thumb:" << cthumb;
	QPixmap p;
	if (!cthumb.hasValue("Thumbnail")) {
		QIcon ico = QIcon::fromTheme("general_default_avatar", QIcon(IMG_AVATAR));
		p = ico.pixmap(160, 160);
	} else {
		p = QPixmap::fromImage(cthumb.thumbnail());
	}
	QPixmap scaled = p.scaled(QSize(160, 160), Qt::KeepAspectRatio, Qt::SmoothTransformation);
	pix->setPixmap(scaled);
	pix->setMask(scaled.mask());
	pix->setMaximumSize(scaled.size());

	QVBoxLayout *rightLayout = new QVBoxLayout;

	QHBoxLayout *hLayout = new QHBoxLayout;
	hLayout->addWidget(thumb);
	hLayout->addLayout(rightLayout);

	QList<QContactDetail> contactDetails = contact->details(QContactPhoneNumber::DefinitionName);
	for (int i = 0; i < contactDetails.size(); i++) {
		QContactPhoneNumber detail = contactDetails.at(i);
		//qDebug() << ">>>> NUMBER: " << detail.number();
		QStringList stl = detail.subTypes();
		//qDebug() << "STL " << stl.size();
		QString s;
		if (stl.size() > 0)
			s = stl.at(0);
		else
			s = QString("Phone");

		QHBoxLayout *hl = new QHBoxLayout;

		sb = NULL;
		QString style = QString("text-align: left;");

		// Highlight selected. Compare the last few digits as sometimes there is a comparison with
		// international calling code prefix.
		if (number.endsWith(detail.number().right(8)))
			style.append(QString("color: rgb(230,230,50);"));

		if (s.compare(QString("Mobile")) == 0) {
			cb = new QPushButton(QIcon(QString(IMG_CELL)), QString("Mobile %1").arg(detail.number()));
			sb = new QPushButton(QIcon(QString(IMG_SMS_READ)), QString("&SMS %1").arg(detail.number()));
			sb->setStyleSheet(style);
		} else {
			cb = new QPushButton(QIcon(QString(IMG_CELL)), QString("%1 %2").arg(s).arg(detail.number()));
		}
		cb->setStyleSheet(style);

		hl->addWidget(cb);
		if (sb)
			hl->addWidget(sb);
		rightLayout->addLayout(hl);
	}

	/* -- TODO need to map dynamic buttons to these functions

	callButton = new QPushButton(tr("&Call"));
	callButton->setDefault(true);
	smsButton = new QPushButton(tr("&SMS"));
	closeButton = new QPushButton(tr("Close"));


	connect(callButton, SIGNAL(clicked()), this, SLOT(callUserClicked()));
	connect(smsButton, SIGNAL(clicked()), this, SLOT(smsUserClicked()));
	connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
	*/

	delete contact;


	mainLayout->addLayout(hLayout);

	setLayout(mainLayout);
}

UserDetails::~UserDetails()
{
}

void UserDetails::callUserClicked()
{
}

void UserDetails::smsUserClicked()
{
}

/*
 * Search for user details and return a reference to the contact.
 * QContact is alloc'd here so the caller needs to free it once
 * done (the allocation is required because the Qt API puts it on
 * the stack which'll get corrupted once falling back to the
 * caller.
 */
QContact *UserDetails::getUserDetails(QString *name)
{
	static QContactManager *cm;

	if (!cm)
		cm = new QContactManager();

	// Find by name
	QContactDetailFilter filter;
	filter.setDetailDefinitionName(QContactDisplayLabel::DefinitionName, QContactDisplayLabel::FieldLabel);

	// Specify the requested value and filter matching criteria
	filter.setValue(*name);
	filter.setMatchFlags(QContactFilter::MatchExactly);

	// Fetch matching contacts list for specified filter
	QList<QContact> matches = cm->contacts(filter);
	if (matches.size() == 0) {
		return NULL;
	}
	//qDebug() << "total matching " << matches.size() << "\n" << matches.at(0);
	QContact *c = new QContact;
	*c = matches.at(0);
	return c;
}

/*
 * TODO: Need to improve the performance of this somehow. The search filter in the
 * contact manager is really slow (~220ms/search).
 */
QPixmap *UserDetails::getUserAvatar(QString &name)
{
	UserAvatar *u;
	for (int i = 0; i < m_avatars.size(); i++) {
		u = m_avatars.at(i);
		if (u->name.compare(name) == 0) {
			//qDebug() << "Fetched " << name << " from cache";
			return u->avatar;
		}
	}

	//qDebug() << "Finding " << name;
	u = new UserAvatar();
	u->name = name;
	const QContact *contact = getUserDetails(&name);
	if (contact == NULL) {
		m_avatars.append(u);
		return NULL;
	}

	QContactThumbnail cthumb = contact->detail(QContactThumbnail::DefinitionName);
	if (!cthumb.hasValue("Thumbnail")) {
		m_avatars.append(u);
		return NULL;
	}

	u->avatar = new QPixmap(QPixmap::fromImage(cthumb.thumbnail()));
	m_avatars.append(u);
	return u->avatar;
}

QList<UserAvatar *> UserDetails::m_avatars;
